import os
import shutil
from pathlib import Path
import sys

# this script copies a directory partially, according to the specified list of files/directories
# files/directories not in this list will be 'copied' by 'ln -s'

def partial_copy(from_dir, to_dir, include_list):
  if not from_dir or not to_dir or not include_list:
      raise ValueError("All parameters must be provided")

  # check the existence of from_dir
  if not os.path.exists(from_dir):
      raise ValueError(f"Source directory {from_dir} does not exist")

  # if the to_dir already exist, ask
  if os.path.exists(to_dir):
    response = input(f"Target directory {to_dir} already exists. Overwrite? (y/n): ")
    if response.lower() != 'y':
      print("Aborted.")
      sys.exit(1)
    shutil.rmtree(to_dir)

  # make sure to_dir exist
  os.makedirs(to_dir, exist_ok=True)

  # get content of from_dir (only direct children, not recursive)
  all_files = [Path(from_dir) / item for item in os.listdir(from_dir)]
  print(f"all_files:\n{all_files}")
  for file in all_files:
      rel_path = file.relative_to(from_dir)
      dest_path = Path(to_dir) / rel_path
      if rel_path not in include_list:
        print(f"full copy: {rel_path}")
        # consider the file type: symlink/dir/file
        if file.is_symlink():
          print(f"{rel_path} is symlink")
          os.makedirs(dest_path.parent, exist_ok=True)
          os.symlink(os.readlink(file), dest_path)
        elif file.is_dir():
          print(f"{rel_path} is directory")
          os.makedirs(dest_path, exist_ok=True)
          shutil.copytree(file, dest_path, dirs_exist_ok=True, symlinks=True)
        else:
          print(f"{rel_path} is file")
          os.makedirs(dest_path.parent, exist_ok=True)
          shutil.copy2(file, dest_path)
      else:  # soft link
        print(f"soft link: {rel_path}")
        os.makedirs(dest_path.parent, exist_ok=True)
        os.symlink(file, dest_path)

def test():
  test_from_path = "/home/algo/geyiheng/utilgyh/camera_extrinsic/test"
  test_to_path = "/home/algo/geyiheng/utilgyh/camera_extrinsic/testp"
  test_include_list = [
      Path("to_adjust.json"),
  ]
  partial_copy(test_from_path, test_to_path, test_include_list)

def main():
  # instruction exmaple: python3 partial_copy.py path1 path2 list
  if len(sys.argv) < 4:
    print("Usage: python3 partial_copy.py <from_dir> <to_dir> <comma_separated_include_list>")
    sys.exit(1)

  from_dir = sys.argv[1]
  to_dir = sys.argv[2]
  include_list = [Path(item.strip()) for item in sys.argv[3].split(",")]
  print(sys.argv[3])
  print(include_list)

  partial_copy(from_dir, to_dir, include_list)

if __name__ == "__main__":
  main()